package com.onpositive.wiki3.catmodels;

import java.io.IOException;
import java.util.Collections;
import java.util.Set;

import com.onpositive.nlp.sequence.ClassifiedSequence;
import com.onpositive.nlp.sequence.ClassifiedSequence.Token;
import com.onpositive.wictionary.access.SemanticVocubalary;
import com.onpositive.wictionary.access.VocubularyAccess;
import com.onpositive.wiki3.db.IWikiDB;
import com.onpositive.wiki3.db.catmodel.Categories;
import com.onpositive.wiki3.db.catmodel.Category;
import com.onpositive.wiki3.db.catmodel.matches.classify.AbstractRecordingMatcher;
import com.onpositive.wiki3.db.catmodel.matches.classify.RelationConstants;
import com.onpositive.wiki3.db.catmodel.matches.classify.RelationStore;

public class PrimaryTextBasedParentMatcher extends AbstractRecordingMatcher {

	protected SemanticVocubalary wp;

	public PrimaryTextBasedParentMatcher(RelationStore store, IWikiDB db)
			throws IOException, ClassNotFoundException {
		super(store);
		wp = new VocubularyAccess(db.getPath() + "/wictionary").getVocubalary();
	}

	public boolean recorded;

	@Override
	public int accept(Category st) {
		Category[] parentsCategories = st.getParentsCategories();
		String string = st.toString();
//		if (!st.toString().equals("reptiles")){
//			return 0;
//		}
		for (Category c : parentsCategories) {
			if (alreadyChild(st, c)) {
				continue;
			}
			if (doCheck(string, c)) {
				System.out.println(c + "->" + st);
				record(RelationConstants.IS_A, c, st);
				recorded = true;
			} else {
				Token core = st.getSequnce().getCore();
				if (core!=null){
					
					if (doCheck(core.name, c)) {
						System.out.println(c + "->" + st);
						record(RelationConstants.IS_A, c, st);
						recorded = true;
						return 0;
					}
				}
				Set<Category> allKnownParents = getAllKnownParents(c);
				// System.out.println(allKnownParents);

				for (Category s : allKnownParents) {
					if (string.endsWith("s")){
						if (core!=null){
							if (wp.canBeUsedAsSubkind(core.name, s.toString())) {
								System.out.println(c + "->" + st);
								record(RelationConstants.IS_A, c, st);
								recorded = true;
							}		
						}
					}
					if (wp.canBeUsedAsSubkind(string, s.toString())) {
						System.out.println(c + "->" + st);
						record(RelationConstants.IS_A, c, st);
						recorded = true;
					}
				}
			}
		}
		return 0;
	}

	protected boolean doCheck(String string, Category c) {
		String replace = string.replace('_', ' ');
		boolean canBeUsedAsSubkind = wp
				.canBeUsedAsSubkind(replace, c.toString().replace('_', ' '));
		if (!canBeUsedAsSubkind) {
			ClassifiedSequence sequnce = c.getSequnce();
			Token core = sequnce.getCore();
			if (core != null) {
				canBeUsedAsSubkind = wp.canBeUsedAsSubkind(string.replace('_', ' '), core.name);
			}
		}
		return canBeUsedAsSubkind;
	}

	protected boolean alreadyChild(Category child, Category parent) {
		Categories categories = toRecord.get(RelationConstants.IS_A);
		Category category = categories.get(child.id());
		if (category != null) {
			return category.hasParent(parent.id());
		}
		return false;
	}

	protected Set<Category> getAllKnownParents(Category st) {
		Categories categories = toRecord.get(RelationConstants.IS_A);
		Category category = categories.get(st.id());
		if (category != null) {
			Set<Category> allParents = category.getAllParents(0);
			allParents.addAll(st.getAllParents(3));
			return allParents;
		}
		return st.getAllParents(4);
	}

}
